package com.xjh.basestudy.designmode.behaviorMode.behaviorMode6_Memento.p2_memento;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author XuJianHua
 * @Date 2022/10/4 20:18
 * @Description
 * 我们首先在第4行加入了一个历史记录列表historyRecords，我们可以把它当作一本有很多页的历史书，顺序记录着每个时间点发生的历史事件，它的当前页码体现于第5行，
 * 即以整型定义的时间点索引historyPosition。注意第33行的备份方法backup()，它能将文档生成的快照加入历史记录列表historyRecords，
 * 做好历史的记录。然后回到第10行的构造方法，这里我们对备忘录进行初始化，并且调用备份方法backup()将文档初始状态保存至备忘录。
 * 同样，文档的所有变更操作完成后都应该将当前文档状态“载入史册”，如之后的插入方法append()以及删除方法delete()中对备份方法的调用。
 *
 * “载入史册”是为了“回溯历史”，因此第43行的撤销方法undo()才能真正实现“昨日重现”。随着历史的推进，之前定义的时间点索引historyPosition会逐渐增大，
 * 要回溯历史就要将索引减小，一直到0指向的最初状态为止。从第44行开始，我们首先进行了校验操作，如果时间点索引在0点位置就不可以回溯了，非法越界操作应当直接返回，
 * 反之则是合法操作，此时可以将时间点索引减1，再将其所对应的历史记录取出，并将内容恢复至当前打开的文档中。
 * 此外，编辑器既然能回溯历史，当然也得有与之相反的功能，也就是第54行的重做方法redo()，实现了这两个功能才能让文档内容在历史时间轴上任意游走。此处略去redo()的代码，请读者自行实践练习。

 */
public class Editor {

    private Doc doc;
    private List<History> historyRecords;// 历史记录列表
    private int historyPosition = -1;// 历史记录当前位置

    public Editor(Doc doc) {
        System.out.println("<<<打开文档" + doc.getTitle());
        this.doc = doc; // 载入文档
        historyRecords = new ArrayList<>();// 初始化历史记录列表
        backup();// 载入文档后保存第一份历史记录
        show();//显示内容
    }

    public void append(String txt) {
        System.out.println("<<<插入操作");
        doc.setBody(doc.getBody() + txt);
        backup();//添加后保存一份历史记录
        show();
    }

    public void save(){
        System.out.println("<<<存盘操作");//模拟存盘操作
    }

    public void delete(){
        System.out.println("<<<删除操作");
        doc.setBody("");
        backup();//删除后保存一份历史记录
        show();
    }

    private void backup() {
        historyRecords.add(doc.createHistory());
        historyPosition++;
    }

    private void show() {// 显示当前文档内容
        System.out.println(doc.getBody());
        System.out.println("文档结束>>>\n");
    }

    public void undo() {// 撤销操作：如按下组合键Ctrl+Z，回到过去
        System.out.println(">>>撤销操作");
        if (historyPosition == 0) {
            return;//到头了，不能再撤销了
        }
        historyPosition--;//历史记录位置回溯一次
        History history = historyRecords.get(historyPosition);
        doc.restoreHistory(history);//取出历史记录并恢复至文档
        show();
    }

    public void redo(){// 重做操作
        //此处省略
    }

}